﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using InkFx.WinControl.Core;
using InkFx.WinControl.Utils;
using DA = Temp_20190707_AForm.DockAlignment;
using DTGS = Temp_20190707_AForm.DockTabGroupState;

namespace Temp_20190707_AForm
{
    public class DockPanel : System.Windows.Forms.Panel
    {
        public DockPanel()
        {
            SetStyle(Win32API.ControlStylesUAORSD, true); 
            base.BackColor = Color.Transparent;
            if (!DesignMode) InitCenterGroup();
        }


        private DockTipForm form2 = null;
        private DockTabGroup m_CenterGroup;
        private List<DockTabGroup> m_ListTabGroup = new List<DockTabGroup>();
        public DockTabGroup CenterGroup
        {
            get { return InitCenterGroup(); }
            set { m_CenterGroup = value; }
        }
        public List<DockTabGroup> ListTabGroup
        {
            get
            {
                m_ListTabGroup.RemoveAll(x => x.DockPanel != this || x.Disposing || x.IsDisposed);
                return m_ListTabGroup;
            }
        }
        public Rectangle RectDockInner
        {
            get
            {
                var size = this.Size;
                var padding = this.Padding;
                return new Rectangle(padding.Left, padding.Top, size.Width - padding.Left - padding.Right, size.Height - padding.Top - padding.Bottom);
            }
        }
        public bool IsSplitMoving { get; set; }


        public DockTabGroup FindTabGroup(SplitterPanel panel)
        {
            var group = this.m_ListTabGroup.Find(x => x.ParentSplitPanel == panel);
            return group;
        }
        public Control FindTabGroupOrSplitControl(SplitterPanel panel, out bool hide)
        {
            hide = false;
            var ctrls = panel.Controls;
            if (ctrls != null && ctrls.Count >= 1)
                foreach (Control ctrl in ctrls)
                {
                    if (ctrl is DockSplitControl) { hide = ((DockSplitControl)ctrl).PanelAllCollapsed; return ctrl; }
                    if (ctrl is DockTabGroup) { hide = ((DockTabGroup)ctrl).State != DTGS.Expand; if (!hide) { ctrl.Visible = true; } return ctrl; }
                }

            hide = true;
            var group = FindTabGroup(panel);
            if (group != null) return group;
            return null;
        }


        public DockTabGroup InitCenterGroup()
        {
            var ctrls = this.Controls;
            if (ctrls.Count >= 1 && ctrls[0] is DockSplitControl) return null;

            if (this.m_CenterGroup != null && !this.m_CenterGroup.Disposing && !this.m_CenterGroup.IsDisposed)
                return this.m_CenterGroup;

            this.m_CenterGroup = new DockTabCenterGroup(this);
            this.m_CenterGroup.Dock = DockStyle.Fill;
            this.m_CenterGroup.Alignment = DockAlignment.Center;
            this.m_CenterGroup.Parent = this;
            return this.m_CenterGroup;
        }


        public void ShowDLPanel()
        {
            if (form2 != null) return;
            form2 = DockTipForm.ShowDLPanel(this);
        }
        public void HideDLPanel()
        {
            try
            {
                if (form2 != null)
                {
                    form2.Close();
                    form2.Dispose();
                    form2 = null;
                }
            }
            catch (Exception) { }
        }
        public void ShowControl(Panel ctrl)
        {
            DockTabGroup group = new DockTabGroup(this, null, DockAlignment.None);
            ctrl.Dock = DockStyle.Fill;
            group.AppendTabPage(null, "测试面板", ctrl);
            DockFloatForm.ShowControl(this, group, Rectangle.Empty);
        }
        public void DoDock(DockTabGroup group)
        {
            DockEventArgs arg = form2 == null ? null : form2.NewDockEventArgs();
            if (arg == null) return;

            #region  原区域拆分

            if (arg.Control != null && arg.TipLayout != null)
            {
                var ctrl1 = arg.Control;
                //if (!(ctrl1 is DockTabGroup)) throw new Exception(string.Format("只允许布局附着到 DockTabGroup 的控件下, 不允许附着到 类型为 '{0}' 的控件下!", ctrl1.GetType().FullName));
                //MessageBox.Show(ctrl.GetType().ToString() + " > " + ctrl1.GetType().ToString());

                this.SuspendLayout();
                if (arg.Alignment == DockAlignment.Center)
                {
                    //MessageBox.Show("中央增加控件: \r\n" + group.GetType().ToString() + " > " + ctrl1.GetType().ToString());

                    group.DisposeFloatForm();
                    group.Alignment = ctrl1.Alignment;
                    group.State = DTGS.Expand;
                    var ctrl0 = group;
                    if (ctrl1 is DockTabCenterGroup)
                    {
                        //如果 DockTabGroup 和 DockTabCenterGroup, 则替换掉CenterGroup的指向
                        ctrl0.Parent = ctrl1.Parent;
                        m_CenterGroup = ctrl0;
                        ctrl1.Parent = null;
                        ctrl1.Dispose();
                    }
                    else { ctrl1.MergeTabGroup(ctrl0); } //直接执行 DockTabGroup 合并
                }
                else
                {
                    group.DisposeFloatForm();
                    group.Alignment = ctrl1.Alignment;
                    group.State = DTGS.Expand;
                    var ctrl0 = group;

                    var parent = ctrl1.Parent;
                    var splitCtrl = new DockSplitControl(this);
                    splitCtrl.Dock = DockStyle.Fill;
                    if (arg.Alignment == DockAlignment.Top || arg.Alignment == DockAlignment.Bottom)
                        splitCtrl.Orientation = Orientation.Horizontal;
                    if (arg.Alignment == DockAlignment.Right || arg.Alignment == DockAlignment.Bottom)
                    { var temp = ctrl0; ctrl0 = ctrl1; ctrl1 = temp; }

                    splitCtrl.Parent = parent;
                    ctrl0.Parent = splitCtrl.Panel1;
                    ctrl1.Parent = splitCtrl.Panel2;
                    //if (parent is DockPanel) { var centerGroup = ((DockPanel)parent).CenterGroup; if (centerGroup != null)centerGroup.Dispose(); }
                }
                this.ResumeLayout(true);
            }

            #endregion

            #region  四边区域扩展

            else if (arg.TipArea != null)
            {
                var ctrls = this.Controls;
                Control ctrl1 = null;
                foreach (var c in ctrls) { if ((c is DockSplitControl) || (c is DockTabGroup)) { ctrl1 = (Control)c; break; } }
                if (ctrl1 == null) return;

                this.SuspendLayout();

                var align = arg.TipArea.Align;
                group.DisposeFloatForm();
                group.Alignment = align;
                group.State = DTGS.Expand;
                Control ctrl0 = group;

                var parent = ctrl1.Parent;
                var splitCtrl = new DockSplitControl(this);
                splitCtrl.Dock = DockStyle.Fill;
                if (align == DockAlignment.Top || align == DockAlignment.Bottom)
                    splitCtrl.Orientation = Orientation.Horizontal;
                if (align == DockAlignment.Right || align == DockAlignment.Bottom)
                { var temp = ctrl0; ctrl0 = ctrl1; ctrl1 = temp; }

                splitCtrl.Parent = parent; 
                ctrl0.Parent = splitCtrl.Panel1;
                ctrl1.Parent = splitCtrl.Panel2;

                this.ResumeLayout(true);
            }

            #endregion

            
        }




        public List<DockAreaInfo> GetAreaInfos()
        {
            const int OFFSET = 6;
            const int SIZE = 30;
            int width = this.Width;
            int height = this.Height;
            Rectangle rectT = new Rectangle((width - SIZE) / 2, OFFSET, SIZE, SIZE);
            Rectangle rectB = new Rectangle((width - SIZE) / 2, height - SIZE - OFFSET, SIZE, SIZE);
            Rectangle rectL = new Rectangle(OFFSET, (height - SIZE) / 2, SIZE, SIZE);
            Rectangle rectR = new Rectangle(width - SIZE - OFFSET, (height - SIZE) / 2, SIZE, SIZE);
            //Rectangle rectC = new Rectangle((width - SIZE) / 2, (height - SIZE) / 2, SIZE, SIZE);


            var areaT = new DockAreaInfo(DockAlignment.Top, this) { Rect = rectT };
            var areaB = new DockAreaInfo(DockAlignment.Bottom, this) { Rect = rectB };
            var areaL = new DockAreaInfo(DockAlignment.Left, this) { Rect = rectL };
            var areaR = new DockAreaInfo(DockAlignment.Right, this) { Rect = rectR };
            //var areaC = new DockAreaInfo(DockAlignment.Center, this) { Rect = rectC };
            var list = new List<DockAreaInfo> { areaT, areaB, areaL, areaR };
            //if (m_CenterGroup == null) list.Add(areaC);
            return list;
        }
        public DockLayoutInfo GetLayoutInfo()
        {
            return GetLayoutInfo(this);
        }
        public DockLayoutInfo GetLayoutInfo(Control parent)
        {
            if (parent == null || parent.Controls.Count <= 0) return null;
            var ctrl = parent.Controls[0];
            if (ctrl == CenterGroup)
            {
                DockLayoutInfo layout = new DockLayoutInfo(DockLayoutEnum.CenterGroup, CenterGroup);
                layout.Rect = GetRect(ctrl);
                return layout;
            }
            else if (ctrl is DockSplitControl)
            {
                var spliter = (DockSplitControl)ctrl;
                DockLayoutInfo layout = new DockLayoutInfo((spliter.Orientation == Orientation.Horizontal ? DockLayoutEnum.Horizontal : DockLayoutEnum.Vertical), spliter);
                layout.Layout1 = GetLayoutInfo(spliter.Panel1);
                layout.Layout2 = GetLayoutInfo(spliter.Panel2);
                layout.Rect = GetRect(ctrl);
                return layout;
            }
            else if (ctrl is DockTabGroup)
            {
                DockLayoutInfo layout = new DockLayoutInfo(DockLayoutEnum.OtherGroup, (DockTabGroup)ctrl);
                layout.Rect = GetRect(ctrl);
                return layout;
            }

            return null;
        }
        private Rectangle GetRect(Control ctrl)
        {
            Rectangle rect1 = this.RectangleToScreen(new Rectangle(Point.Empty, this.Size));
            Rectangle rect2 = ctrl.RectangleToScreen(new Rectangle(Point.Empty, ctrl.Size));
            Rectangle rect3 = new Rectangle(rect2.X - rect1.X, rect2.Y - rect1.Y, rect2.Width, rect2.Height);
            return rect3;
        }


        private const int DOCK_SIZE = 25;
        public void DoLayout()
        {
            var listGroup = ListTabGroup;
            bool top = listGroup.Find(x => x.Alignment == DockAlignment.Top && (x.State == DTGS.Collapse || x.State == DTGS.Popup)) != null;
            bool bottom = listGroup.Find(x => x.Alignment == DockAlignment.Bottom && (x.State == DTGS.Collapse || x.State == DTGS.Popup)) != null;
            bool left = listGroup.Find(x => x.Alignment == DockAlignment.Left && (x.State == DTGS.Collapse || x.State == DTGS.Popup)) != null;
            bool right = listGroup.Find(x => x.Alignment == DockAlignment.Right && (x.State == DTGS.Collapse || x.State == DTGS.Popup)) != null;

            this.Padding = new Padding((left ? DOCK_SIZE : 0), (top ? DOCK_SIZE : 0), (right ? DOCK_SIZE : 0), (bottom ? DOCK_SIZE : 0));
        }

        #region  重置布局

        public int LayoutSuspendCount { get; private set; }
        public bool IsLayoutSuspended { get { return LayoutSuspendCount >= 1; } }

        public virtual new void SuspendLayout()
        {
            LayoutSuspendCount++;
            base.SuspendLayout();
        }
        public virtual new void ResumeLayout()
        {
            this.ResumeLayout(true);
        }
        public virtual new void ResumeLayout(bool performLayout)
        {
            LayoutSuspendCount--;

            if (LayoutSuspendCount <= 0)
            {
                LayoutSuspendCount = 0;
                ResetLayout();
            }

            base.ResumeLayout(performLayout);
            this.Refresh();


            //var list = m_ListSuspendLayoutContrl;
            //if (list != null && list.Count >= 0)
            //{
            //    var list2 = new List<Control>(list);
            //    foreach (var ctrl in list2)
            //    {
            //        if (ctrl.Disposing || ctrl.IsDisposed) continue;
            //        if (ctrl is DockSplitControl) { ((DockSplitControl)ctrl).DoLayout(); }
            //        //if (ctrl is DockTabGroup) { ((DockTabGroup)ctrl).DoLayout(); }
            //    }
            //    m_ListSuspendLayoutContrl.Clear();
            //    //this.DoLayout();
            //}
        }
        //private List<Control> m_ListSuspendLayoutContrl=new List<Control>();
        //public void SuspendLayoutControl(Control ctrl)
        //{
        //    if (!(ctrl is DockSplitControl) && !(ctrl is DockTabGroup)) return;
        //    if (m_ListSuspendLayoutContrl.Contains(ctrl)) return;
        //    m_ListSuspendLayoutContrl.Add(ctrl);
        //}

        public void ResetLayout()
        {
            var ctrls = this.Controls;
            foreach (var ctrl in ctrls)
            {
                if (ctrl is DockSplitControl) { ((DockSplitControl)ctrl).ResetLayout(); }
            }
            this.DoLayout();
        }

        #endregion

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            this.Refresh();
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            this.Refresh();
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            this.Refresh();
        }
        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            this.Refresh();
        }
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            this.Refresh();
        }
        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);

            if (m_HashRectPage == null || m_HashRectPage.Count <= 0) return;
            Point point1 = Control.MousePosition;
            Point point2 = this.PointToClient(point1);

            Hashtable hash = null;
            lock (m_HashRectPage.SyncRoot) hash = (Hashtable)m_HashRectPage.Clone();

            //this.SuspendLayout();
            foreach (var key in hash.Keys)
            {
                var value = hash[key];
                if (!(key is Rectangle) || !(value is DockTabGroupPage)) continue;
                var rect = (Rectangle)key;
                var page = (DockTabGroupPage)value;
                if (page.ParentGroup != null && !page.ParentGroup.Disposing && !page.ParentGroup.IsDisposed && rect.Contains(point2))
                {
                    //group.Riveted = true;
                    DockPopPanel.TogglePopGroup(page);
                }
            }
            //this.ResumeLayout(true);

            //this.DoLayout();
        }


        protected override void OnPaint(PaintEventArgs e)
        {
            //if (m_DrawingSplitter) return;
            base.OnPaint(e);


            Graphics g = e.Graphics;

            var listGroup = ListTabGroup;
            var listTop = listGroup.FindAll(x => x.Alignment == DockAlignment.Top && (x.State == DTGS.Collapse || x.State == DTGS.Popup));
            var listBottom = listGroup.FindAll(x => x.Alignment == DockAlignment.Bottom && (x.State == DTGS.Collapse || x.State == DTGS.Popup));
            var listLeft = listGroup.FindAll(x => x.Alignment == DockAlignment.Left && (x.State == DTGS.Collapse || x.State == DTGS.Popup));
            var listRight = listGroup.FindAll(x => x.Alignment == DockAlignment.Right && (x.State == DTGS.Collapse || x.State == DTGS.Popup));

            lock (m_HashRectPage.SyncRoot) m_HashRectPage.Clear();
            OnPaintRivetedTabGroup(g, DockAlignment.Top, listTop);
            OnPaintRivetedTabGroup(g, DockAlignment.Bottom, listBottom);
            OnPaintRivetedTabGroup(g, DockAlignment.Left, listLeft);
            OnPaintRivetedTabGroup(g, DockAlignment.Right, listRight);

            //if (this.IsSplitMoving)
            //{
            //    //RepaintSplitterRect();
            //    var handle = this.Handle; //Win32API.GetDesktopWindow();
            //    Win32API.DrawSplitHelper(handle, m_RectSplitter);
            //    //this.Invalidate(true);
            //    //this.Refresh();
            //}
        }
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            //if (m_DrawingSplitter) return;
            base.OnPaintBackground(e);
        }

        private Hashtable m_HashRectPage =  Hashtable.Synchronized(new Hashtable());
        protected virtual void OnPaintRivetedTabGroup(Graphics g, DockAlignment align, List<DockTabGroup> listGroup)
        {
            if (g == null || align == DockAlignment.None || align == DockAlignment.Center) return;
            if (listGroup == null || listGroup.Count <= 0) return;

            if (align == DockAlignment.Top)
            {
                #region  Top

                int x = this.Padding.Left;
                int y = 0;
                for (int i = 0, len = listGroup.Count; i < len; i++)
                {
                    var group = listGroup[i];
                    foreach (var page in group.ListPage)
                    {
                        var backColor = (page == null || page.Control == null) ? Color.AliceBlue : page.Control.BackColor;
                        Rectangle rect = new Rectangle(x, y, 70, DOCK_SIZE - 3);
                        g.FillRectangle(new SolidBrush(backColor), rect);
                        x = x + rect.Width + 1;
                        lock (m_HashRectPage.SyncRoot) m_HashRectPage[rect] = page;
                    }
                }

                #endregion
            }
            else if (align == DockAlignment.Bottom)
            {
                #region Bottom

                int x = this.Padding.Left;
                int y = this.Height - DOCK_SIZE + 3;
                for (int i = 0, len = listGroup.Count; i < len; i++)
                {
                    var group = listGroup[i];
                    foreach (var page in group.ListPage)
                    {
                        var backColor = (page == null || page.Control == null) ? Color.AliceBlue : page.Control.BackColor;
                        Rectangle rect = new Rectangle(x, y, 70, DOCK_SIZE - 3);
                        g.FillRectangle(new SolidBrush(backColor), rect);
                        x = x + rect.Width + 1;
                        lock (m_HashRectPage.SyncRoot) m_HashRectPage[rect] = page;
                    }
                }

                #endregion
            }
            else if (align == DockAlignment.Left)
            {
                #region Left

                int x = 0;
                int y = this.Padding.Top;
                for (int i = 0, len = listGroup.Count; i < len; i++)
                {
                    var group = listGroup[i];
                    foreach (var page in group.ListPage)
                    {
                        var backColor = (page == null || page.Control == null) ? Color.AliceBlue : page.Control.BackColor;
                        Rectangle rect = new Rectangle(x, y, DOCK_SIZE - 3, 70);
                        g.FillRectangle(new SolidBrush(backColor), rect);
                        y = y + rect.Height + 1;
                        lock (m_HashRectPage.SyncRoot) m_HashRectPage[rect] = page;
                    }
                }

                #endregion
            }
            else if (align == DockAlignment.Right)
            {
                #region Right

                int x = this.Width - DOCK_SIZE + 3;
                int y = this.Padding.Top;
                for (int i = 0, len = listGroup.Count; i < len; i++)
                {
                    var group = listGroup[i];
                    foreach (var page in group.ListPage)
                    {
                        var backColor = (page == null || page.Control == null) ? Color.AliceBlue : page.Control.BackColor;
                        Rectangle rect = new Rectangle(x, y, DOCK_SIZE - 3, 70);
                        g.FillRectangle(new SolidBrush(backColor), rect);
                        y = y + rect.Height + 1;
                        lock (m_HashRectPage.SyncRoot) m_HashRectPage[rect] = page;
                    }
                }

                #endregion
            }
        }

        public Rectangle m_RectSplitter;
        public SplitterForm splitter;
        public void DrawSplitter(Rectangle rect)
        {
            try
            {
                ////m_DrawingSplitter = true;
                //m_RectSplitter = rect;
                //Win32API.DrawSplitHelper(this.Handle, m_RectSplitter);
                ////this.Invalidate(RectDockInner, true);
                //this.Invalidate(rect, true);
                ////this.Update();

                ////this.Refresh();

                if (splitter == null)
                {
                    splitter = SplitterForm.BeginSplitter(this.RectangleToScreen(rect));
                }

                splitter.ShowSplitter(this.RectangleToScreen(rect));
            }
            finally { /*m_DrawingSplitter = false;*/ }
        }

        public void EndSplitter()
        {
            if (splitter != null)
            {
                splitter.EndSplitter();
                splitter = null;
            }
        }


    }

    public class DockLayoutInfo
    {
        public DockLayoutInfo(DockLayoutEnum @enum, DockTabGroup ctrl)
        {
            this.Enum = @enum;
            this.TabGroup = ctrl;
        }
        public DockLayoutInfo(DockLayoutEnum @enum, DockSplitControl ctrl)
        {
            this.Enum = @enum;
            this.SplitControl = ctrl;
        }

        public DockLayoutEnum Enum { get; set; }
        public Rectangle Rect { get; set; }
        public DockTabGroup TabGroup { get; set; }
        public DockSplitControl SplitControl { get; set; }
        public DockLayoutInfo Layout1 { get; set; }
        public DockLayoutInfo Layout2 { get; set; }
        public DockTipGroupRect TipRect
        {
            get
            {
                const int SIZE = 90;
                Rectangle rect1 = this.Rect;
                Rectangle rect2 = new Rectangle(0, 0, SIZE, SIZE);
                if (rect1.Width < rect2.Width || rect1.Height < rect2.Height) return DockTipGroupRect.Empty;
                Rectangle rect3 = new Rectangle((rect1.X) + (rect1.Width - rect2.Width) / 2, (rect1.Y) + (rect1.Height - rect2.Height) / 2, rect2.Width, rect2.Height);
                return new DockTipGroupRect(rect3);
            }
        }
        public DockPanel DockPanel
        {
            get
            {
                if (TabGroup != null && TabGroup.DockPanel != null) return TabGroup.DockPanel;
                if (SplitControl != null && SplitControl.DockPanel != null) return SplitControl.DockPanel;
                return null;
            }
        }


        public bool MouseInRect()
        {
            var dockPanel = DockPanel;
            if (dockPanel == null) return false;
            var point1 = System.Windows.Forms.Control.MousePosition;
            var point2 = dockPanel.PointToClient(point1);
            return Rect.Contains(point2);
        }
        public DockAlignment MouseInTipRect()
        {
            var dockPanel = DockPanel;
            if (dockPanel == null) return DockAlignment.None;
            var point1 = System.Windows.Forms.Control.MousePosition;
            var point2 = dockPanel.PointToClient(point1);
            return TipRect.Contains(point2);
        }

        [Obsolete("作废", true)]
        public DockLayoutInfo GetContent()
        {
            if (this.Enum == DockLayoutEnum.CenterGroup) return this;

            var result1 = Layout1 == null ? null : Layout1.GetContent();
            if (result1 != null) return result1;

            var result2 = Layout2 == null ? null : Layout2.GetContent();
            if (result2 != null) return result2;

            return null;
        }
        public List<DockLayoutInfo> GetTabGroups()
        {
            if (this.Enum == DockLayoutEnum.CenterGroup) return new List<DockLayoutInfo> { this };
            if (this.Enum == DockLayoutEnum.OtherGroup) return new List<DockLayoutInfo> { this };

            List<DockLayoutInfo> list = new List<DockLayoutInfo>();

            var result1 = Layout1 == null ? null : Layout1.GetTabGroups();
            if (result1 != null) list.AddRange(result1);

            var result2 = Layout2 == null ? null : Layout2.GetTabGroups();
            if (result2 != null) list.AddRange(result2);

            return list;
        }
    }

    public class DockAreaInfo
    {
        public DockAreaInfo(DockAlignment align, DockPanel ctrl)
        {
            this.Align = align;
            this.DockPanel = ctrl;
        }

        public DockAlignment Align { get; set; }
        public DockPanel DockPanel { get; set; }
        public Rectangle Rect { get; set; }
        public bool MouseInRect()
        {
            var dockPanel = DockPanel;
            if (dockPanel == null) return false;
            var point1 = System.Windows.Forms.Control.MousePosition;
            var point2 = dockPanel.PointToClient(point1);
            return Rect.Contains(point2);
        }
        public DockAlignment MouseInTipRect()
        {
            if (MouseInRect()) return Align;
            return DockAlignment.None;
        }
    }


    public struct DockTipGroupRect
    {
        public static readonly DockTipGroupRect Empty = new DockTipGroupRect();

        public DockTipGroupRect(Rectangle rect) : this()
        {
            int width = rect.Width;
            int height = rect.Height;
            RectFull = rect;
            RectCenter = new Rectangle(RectFull.X + (width / 3), RectFull.Y + (height / 3), width / 3, height / 3);
            RectTop = new Rectangle(RectFull.X + (width / 3), RectFull.Y, width / 3, height / 3);
            RectBottom = new Rectangle(RectFull.X + (width / 3), RectFull.Y + (height * 2 / 3), width / 3, height / 3);
            RectLeft = new Rectangle(RectFull.X, RectFull.Y + (height / 3), width / 3, height / 3);
            RectRight = new Rectangle(RectFull.X + (width * 2 / 3), RectFull.Y + (height / 3), width / 3, height / 3);
        }

        public Rectangle RectFull { get; set; }
        public Rectangle RectCenter { get; set; }
        public Rectangle RectTop { get; set; }
        public Rectangle RectBottom { get; set; }
        public Rectangle RectLeft { get; set; }
        public Rectangle RectRight { get; set; }

        public int Width { get { return RectFull.Width; } }
        public int Height { get { return RectFull.Height; } }

        public DockAlignment Contains(Point point)
        {
            if(RectCenter.Contains(point)) return DockAlignment.Center;
            if(RectTop.Contains(point)) return DockAlignment.Top;
            if(RectBottom.Contains(point)) return DockAlignment.Bottom;
            if(RectLeft.Contains(point)) return DockAlignment.Left;
            if(RectRight.Contains(point)) return DockAlignment.Right;
            return DockAlignment.None;
        }
    }


    public enum DockLayoutEnum
    {
        CenterGroup,
        OtherGroup,
        Vertical,
        Horizontal,
    }

    public enum DockAlignment
    {
        None,
        Top,
        Bottom,
        Left,
        Right,
        Center,
        FloatCenter,
    }

    public class DockEventArgs : EventArgs
    {
        public DockTabGroup Control;
        public DockAreaInfo TipArea;
        public DockLayoutInfo TipLayout;
        public DockAlignment Alignment;
    }

}
